﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;

namespace Alos.Common
{
    public class Log
    {
        static string _logName = "错误日志";
        static Object obj = new Object();
        static System.Timers.Timer _timer = new System.Timers.Timer(1000 * 30);
        static DateTime writeDate = DateTime.Now;
        static TimeSpan ts = new TimeSpan();
        static int idx = 0;
        static List<KeyValuePair<string, Exception>> tmpException = new List<KeyValuePair<string, Exception>>(), curException = new List<KeyValuePair<string, Exception>>(), eptException = new List<KeyValuePair<string, Exception>>();
        public Log()
        {
        }
        public static void errorlog(Exception msg)
        {
            if (!_timer.Enabled)
            {
                _timer.Elapsed += new ElapsedEventHandler(Second_Elapsed);
                _timer.AutoReset = true;
                _timer.Interval = 1000 * 30;
                _timer.Enabled = true;
            }
            WriterLog(msg);
        }

        #region 向暂存中写入日志
        /// <summary>
        /// 向暂存中写入日志
        /// </summary>
        /// <param name="ex"></param>
        static void WriterLog(Exception ex)
        {
            if (!tmpException.Exists(tmp => tmp.Key == ex.Message))
                tmpException.Add(new KeyValuePair<string, Exception>(ex.Message, ex));
        }
        #endregion

        #region 向日志文件写入数据
        /// <summary>
        /// 向日志文件写入数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void Second_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ts = (DateTime.Now - writeDate);
            if (ts.TotalMinutes >= 5 || tmpException.Count >= 100)
            {
                curException = tmpException;
                tmpException = eptException;
                System.DateTime tm = DateTime.Now;

                String LogDir = ConfigurationManager.AppSettings["LogDir"];
                String path = (System.AppDomain.CurrentDomain.BaseDirectory + (string.IsNullOrEmpty(LogDir) ? "/App_Log/" + DateTime.Now.ToString("yyyy-MM-dd") : LogDir)).Replace("/", @"\").Replace(@"\\", @"\");

                try
                {
                    Monitor.Enter(obj);
                    if (!Directory.Exists(path)) Directory.CreateDirectory(path);
                    var fileInfo = new DirectoryInfo(path).GetFiles();
                    Array.Sort(fileInfo, (x, y) => x.CreationTime.CompareTo(y.CreationTime));
                    if (fileInfo.Length > 0)
                    {
                        if (fileInfo[fileInfo.Length - 1].Length >= 10485760)
                            idx = fileInfo.Length;
                        else
                            idx = fileInfo.Length - 1;
                    }
                    else
                        idx = 0;
                    string logPath = path + "\\" + _logName + "-" + idx + ".txt";
                    StreamWriter sw = null;

                    try
                    {
                        sw = File.Exists(logPath) ? File.AppendText(logPath) : File.CreateText(logPath);
                        curException.ForEach(ex =>
                        {
                            sw.WriteLine(ex.ToString() + "----------【" + tm + "】");
                        });

                    }
                    finally
                    {
                        sw.Close();
                    }
                    curException.Clear();
                    eptException = curException;
                    writeDate = DateTime.Now;
                }
                finally
                {
                    Monitor.Exit(obj);
                }
            }
        }
        #endregion
    }
}
